/*
 	PureMVC StateMachine Utility
 	Copyright (c) 2008 neil manuell
  	Your reuse is governed by the Creative Commons Attribution 3.0 License
 */
package org.puremvc.as3.multicore.utilities.statemachine
{

	import org.puremvc.as3.multicore.interfaces.INotification;
	import org.puremvc.as3.multicore.patterns.mediator.Mediator;

	public class StateMachine extends Mediator
	{
		
		public static const NAME:String = "StateMachine"
		
		public function StateMachine()
		{
			super(NAME);
			
		}
		
		public function registerStateChangeCommands(enterCommand:Class, exitCommand:Class, state:State):void{
			
			facade.registerCommand(getNoteName(state, StateConstants.ENTER), enterCommand);
    		facade.registerCommand(getNoteName(state, StateConstants.EXIT), exitCommand);
				
		}
		
		public function removeStateChangeCommands(state:State):void{
			
			facade.removeCommand(getNoteName(state, StateConstants.ENTER));
  			facade.removeCommand(getNoteName(state, StateConstants.EXIT));
				
		}
		
		public function get currentState():State
		{
			return State(viewComponent);
		}
		
		public function changeState(state:State):void
		{
			
			if(currentState && state.name == currentState.name) return;
				
			exitState(currentState);
			enterState(state);
			
		}
		
		override public function listNotificationInterests():Array{
			return [StateConstants.CHANGE_STATE]
		}
		
		override public function handleNotification(notification:INotification):void{
			switch(notification.getName()){
				
				case StateConstants.CHANGE_STATE:
					changeState(State(notification.getBody()))
					break;
				
			}
		}
		
		private function exitState(state:State):void
		{
			if(currentState == null) return;
    		sendNotification(getNoteName(state, StateConstants.EXIT), state);
		}
		
		private function enterState(state:State):void
		{
			viewComponent = state;
    		sendNotification(getNoteName(state, StateConstants.ENTER), state);
		}
		
		private function getNoteName(state:State, phase:String):String
		{
		     return  state.name + phase;
		}
	}
}